/*
 * @Description: Copyright (C) 2018 hakeem, Inc. All Rights Reserved.
 * @Author: yanhaijiang
 * @Date: 2018-12-30 23:09:25
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2018-12-31 18:37:02
 */

// 作为对象调用
// 作为普通函数调用
// 构造器调用
// Function.prototype.call 和 Function.prototype.apply 调用

var obj = {
    a: 1,
    getA: function() {
        alert(this === obj); // 输出:true alert ( this.a ); // 输出: 1
    }
};

window.name = 'globalName';
var myObject = {
    name: 'sven',
    getName: function() {
        return this.name;
    }
};

// 构造器调用
var MyClass = function() {
    this.name = 'sven';
};

var MyClass = function() {
    this.name = 'sven';
    return { // 显式地返回一个对象
        name: 'anne'
    }
};

// 跟普通的函数调用相比，用 Function.prototype.call 或Function.prototype.apply 可以动态地 改变传入函数的 this
var obj1 = {
    name: 'sven',
    getName: function() {
        return this.name;
    }
};
var obj2 = {
    name: 'anne'
};

// apply
var func = function(a, b, c) {
    alert([a, b, c]); // 输出 [ 1, 2, 3 ]
};
func.apply(null, [1, 2, 3]);

var func = function(a, b, c) {
    alert([a, b, c]); // 输出 [ 1, 2, 3 ]
};

func.call(null, 1, 2, 3);

// call和apply的用途

var obj1 = {
    name: 'sven'
};
var obj2 = {
    name: 'anne'
};
window.name = 'window';
var getName = function() {
    alert(this.name);
};
getName(); // 输出：window
getName.call(obj1); // 输出: sven
getName.call(obj2); // 输出: anne

// 借用其他对象的方法
(function() {
    Array.prototype.push.call(arguments, 3);
    console.log(arguments); // 输出[1,2,3]
})(1, 2);